package com.example.casper.Experiment2024.gone;

import static android.app.Activity.RESULT_OK;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.net.Uri;
import android.os.Bundle;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.Toast;

import com.example.casper.Experiment2024.R;
import com.example.casper.Experiment2024.items.Location;
import com.example.casper.Experiment2024.items.locationSave;
import com.example.casper.Experiment2024.locationDetailsInputActivity;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class ListFragment extends Fragment {
    private RecyclerView recyclerView;
    private RecyclerViewLocationAdapter adapter;
    private List<Location> List;
    private ActivityResultLauncher<Intent> addItemLauncher;
    private ActivityResultLauncher<Intent> updateItemLauncher;

    private Spinner spinnerProvince;
    public String selectedProvince;
    private static final int REQUEST_CODE_LOCATION_DETAILS = 1;
    private SharedViewModel sharedViewModel1;
    private SharedViewModel sharedViewModel2;
    private Button addButton,shareButton,PrtScButton,deleteButton,updateButton,pickImageButton;
    private ActivityResultLauncher<Intent> pickImageLauncher;
    private Location selectedLocationForImageUpdate;
    private int positionForImageUpdate;

    public ListFragment() {
        // Required empty public constructor
    }

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }

    public static ListFragment newInstance() {
        ListFragment fragment = new ListFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootViewer = inflater.inflate(R.layout.fragment_list, container, false);

        sharedViewModel1 = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        sharedViewModel2 = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        recyclerView = rootViewer.findViewById(R.id.recyclerview_items);
        recyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));

        List = new ArrayList<>();
        locationSave databank = new locationSave(requireActivity());
        List = databank.readItems();

        registerForContextMenu(recyclerView);

        spinnerProvince = rootViewer.findViewById(R.id.spinner_province);
        initializeProvinceSpinner();

        spinnerProvince.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
                selectedProvince = parentView.getItemAtPosition(position).toString();
                showLocationsByProvince(selectedProvince);
                sharedViewModel1.setSelectedProvince(selectedProvince);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parentView) {
                showLocationsByProvince("全部");
                sharedViewModel2.setSelectedProvince("全部");
            }
        });

//        sharedViewModel.getLocationUpdated().observe(getViewLifecycleOwner(), newLocation -> {
//            if (newLocation != null) {
//                // 更新列表
//                refreshLocationList();
//            }
//        });

        sharedViewModel2.getListRefreshNeeded().observe(getViewLifecycleOwner(), isRefreshNeeded -> {
            if (isRefreshNeeded) {
                refreshLocationList();
            }
        });
        // 初始化按钮
        addButton = rootViewer.findViewById(R.id.button_add);
        deleteButton = rootViewer.findViewById(R.id.button_delete);
        updateButton = rootViewer.findViewById(R.id.button_update);
        pickImageButton = rootViewer.findViewById(R.id.button_pick_image);
        PrtScButton = rootViewer.findViewById(R.id.button_Prtsc);



        // 设置按钮点击事件
        addButton.setOnClickListener(v -> addLocation());
        deleteButton.setOnClickListener(v -> deleteLocation());
        updateButton.setOnClickListener(v -> updateLocation());
        pickImageButton.setOnClickListener(v -> pickImage());
        PrtScButton.setOnClickListener(v -> captureScreen());

        return rootViewer;
    }

//选择要处理location
    private void showLocationSelectionDialog(String title, List<Location> locations, LocationSelectionCallback callback) {
    if (locations.isEmpty()) {
        Toast.makeText(getContext(), "No locations available", Toast.LENGTH_SHORT).show();
        return;
    }
    // 创建一个包含所有 Location 名称的数组
    String[] locationNames = new String[locations.size()];
    for (int i = 0; i < locations.size(); i++) {
        locationNames[i] = locations.get(i).getLocationName();
    }

    // 显示选择对话框
    AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
    builder.setTitle(title)
            .setItems(locationNames, (dialog, which) -> {
                // 用户选择了第 which 个位置，回调处理选择
                callback.onLocationSelected(locations.get(which), which);
            })
            .setNegativeButton("Cancel", null)
            .show();
}

    // 定义回调接口
    public interface LocationSelectionCallback {
        void onLocationSelected(Location location, int position);
    }

    public void refreshLocationList() {
        locationSave databank = new locationSave(getContext());
        List<Location> locations = databank.readItems();
        adapter.updateList(locations);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addItemLauncher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == RESULT_OK) {
                        Intent data = result.getData();
                        String provinceName = data.getStringExtra("province_name");
                        String cityName = data.getStringExtra("city_name");
                        String districtName = data.getStringExtra("district_name");
                        String fullName = provinceName + cityName + districtName;
                        String feeling = data.getStringExtra("feeling");
                        int position = data.getIntExtra("position", 0) + 1;
                        getLatLngByAddress(provinceName, fullName, feeling, position,false);
                    } else if (result.getResultCode() == Activity.RESULT_CANCELED) {
                        Toast.makeText(getContext(), "Operation canceled", Toast.LENGTH_SHORT).show();
                    }
                }
        );

        updateItemLauncher = registerForActivityResult(
                new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    if (result.getResultCode() == RESULT_OK) {
                        Intent data = result.getData();
                        if (data != null) {
                            // 获取更新后的数据
                            int position = data.getIntExtra("position", 0);
                            String provinceName = data.getStringExtra("province_name");
                            String cityName = data.getStringExtra("city_name");
                            String districtName = data.getStringExtra("district_name");
                            String fullName = provinceName + cityName + districtName;
                            String feeling = data.getStringExtra("feeling");
                            Uri imgpath=data.getParcelableExtra("PicPath");
                            getLatLngByAddress(provinceName, fullName, feeling, position,true);

                        }
                    } else if (result.getResultCode() == Activity.RESULT_CANCELED) {
                        // Handle cancellation
                    }
                }
        );
    }


    public void addLocation() {
        Intent intentAdd = new Intent(getContext(), locationDetailsInputActivity.class);
        intentAdd.putExtra("requestCode", 100);
        addItemLauncher.launch(intentAdd);
    }





    private void deleteLocation() {
        // 确保 List 不为空
        if (List.isEmpty()) {
            Toast.makeText(getContext(), "No items to delete", Toast.LENGTH_SHORT).show();
            return;
        }

        // 使用通用选择对话框让用户选择要删除的 Location 项目
        showLocationSelectionDialog("Choose a location to delete", List, (selectedLocation, position) -> {
            // 删除选中的位置
            Location removedLocation = List.remove(position);

            // 更新适配器数据
            adapter.updateList(List);

            // 保存更新后的列表
            locationSave databank = new locationSave(getContext());
            databank.saveGoneItems(new ArrayList<>(List));

            // 显示删除成功的提示
            Toast.makeText(getContext(), "Location deleted", Toast.LENGTH_SHORT).show();
        });
    }

    private void updateLocation() {
        showLocationSelectionDialog("Choose a location to update", List, (selectedLocation, position) -> {
            // 跳转到更新界面并传递选中 Location 的数据
            Intent intentUpdate = new Intent(getContext(), locationDetailsInputActivity.class);
            intentUpdate.putExtra("location", selectedLocation); // 将整个对象传递
            intentUpdate.putExtra("position", position); // 保存位置索引

            updateItemLauncher.launch(intentUpdate);
        });
    }

    private void pickImage() {
        // 确保列表不为空
        if (List.isEmpty()) {
            Toast.makeText(getContext(), "No items to update image", Toast.LENGTH_SHORT).show();
            return;
        }

        // 使用通用选择对话框，让用户选择要更新图片的 Location
        showLocationSelectionDialog("Choose a location to update image", List, (selectedLocation, position) -> {
            // 一旦用户选择了一个位置，就调用选择图片的逻辑
            pickImageFromGallery(selectedLocation, position);

        });
    }

    private void pickImageFromGallery(Location selectedLocation, int position) {
        selectedLocationForImageUpdate = selectedLocation;
        positionForImageUpdate = position;

        Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.setType("image/*");
        startActivityForResult(intent, 100); // 启动图片选择器
    }
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == 100 && resultCode == RESULT_OK && data != null) {
            Uri selectedImageUri = data.getData(); // 获取选择的图片的 URI

            if (selectedImageUri != null && selectedLocationForImageUpdate != null) {
                // 更新 Location 的图片路径
                selectedLocationForImageUpdate.setPicPath(selectedImageUri);

                // 刷新 RecyclerView
                adapter.notifyItemChanged(positionForImageUpdate);

                // 保存更新后的列表
                locationSave databank = new locationSave(getContext());
                databank.saveGoneItems(new ArrayList<>(List));

                Toast.makeText(getContext(), "Location image updated", Toast.LENGTH_SHORT).show();
            }
        }
    }



    private void getLatLngByAddress(String provinceName, String fullName, String feeling, int position,boolean isUpdate) {
        new Thread(() -> {
            try {
                String apiKey = "7H7BZ-BT73V-XGOP6-56ESQ-66Q4S-BTFDC";
                String url = "https://apis.map.qq.com/ws/geocoder/v1/?address=" + URLEncoder.encode(fullName, "UTF-8") + "&key=" + apiKey;
                URL obj = new URL(url);
                HttpURLConnection con = (HttpURLConnection) obj.openConnection();
                con.setRequestMethod("GET");

                BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                String inputLine;
                StringBuilder response = new StringBuilder();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                in.close();

                requireActivity().runOnUiThread(() -> parseJsonResponse(provinceName, response.toString(), fullName, feeling, position,isUpdate));
            } catch (Exception e) {
                e.printStackTrace();
                requireActivity().runOnUiThread(() -> Toast.makeText(getContext(), "Failed to get latitude and longitude", Toast.LENGTH_SHORT).show());
            }
        }).start();
    }

    private void parseJsonResponse(String provinceName, String jsonStr, String fullName, String feeling, int position, boolean isUpdate) {
        try {
            JSONObject jsonObject = new JSONObject(jsonStr);
            int statusCode = jsonObject.getInt("status");

            if (statusCode == 0) {
                JSONObject location = jsonObject.getJSONObject("result").getJSONObject("location");
                double latitude = location.getDouble("lat");
                double longitude = location.getDouble("lng");

                if (isUpdate) {
                    // 更新现有对象
                    Location existingLocation = List.get(position);
                    existingLocation.setLocationName(fullName);
                    existingLocation.setLatitude(latitude);
                    existingLocation.setLongitude(longitude);
                    existingLocation.setFeeling(feeling);
                    existingLocation.setProvince(provinceName);
                    adapter.notifyItemChanged(position);
                } else {
                    // 添加新对象
                    Uri uri = Uri.parse("android.resource://" + getContext().getPackageName() + "/" + R.drawable.foot);
                    Location newLocation = new Location(uri, fullName, latitude, longitude, feeling);
                    newLocation.setProvince(provinceName);
                    List.add(newLocation);
                    adapter.notifyItemInserted(List.size() - 1);
                }

                // 保存更新后的列表
                locationSave databank = new locationSave(getContext());
                databank.saveGoneItems(new ArrayList<>(List));
                showLocationsByProvince(sharedViewModel1.getSelectedProvince().getValue());
            } else if (statusCode == 121) {
                Toast.makeText(getContext(), "API key daily limit reached", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(getContext(), "Failed to get latitude and longitude", Toast.LENGTH_SHORT).show();
            }
        } catch (JSONException e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "Failed to parse JSON", Toast.LENGTH_SHORT).show();
        }
    }


    public void showLocationsByProvince(String province) {
        locationSave databank = new locationSave(requireActivity());
        List = databank.readItems();
        if (adapter == null) {
            // 确保 adapter 已经被初始化
            adapter = new RecyclerViewLocationAdapter(requireActivity(),List);
            recyclerView.setAdapter(adapter);
        }
        if ("全部".equals(province)) {
            adapter.updateList(new ArrayList<>(List));
        } else {
            List<Location> filteredList = List.stream()
                    .filter(location -> province.equals(location.getProvince()))
                    .collect(Collectors.toList());
            adapter.updateList(filteredList);
        }
    }


    private void initializeProvinceSpinner() {
        ArrayList<String> provinces = new ArrayList<>(Arrays.asList(
                "全部", "北京市", "天津市", "上海市", "重庆市",
                "河北省", "山西省", "辽宁省", "吉林省", "黑龙江省",
                "江苏省", "浙江省", "安徽省", "福建省", "江西省", "山东省",
                "河南省", "湖北省", "湖南省", "广东省", "海南省",
                "四川省", "贵州省", "云南省", "陕西省", "甘肃省", "青海省",
                "台湾省", "内蒙古自治区", "广西壮族自治区", "西藏自治区",
                "宁夏回族自治区", "新疆维吾尔自治区", "香港特别行政区", "澳门特别行政区"
        ));
        ArrayAdapter<String> provinceAdapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_spinner_item, provinces);
        provinceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerProvince.setAdapter(provinceAdapter);
    }

    private void captureScreen() {
        View rootView = getView();
        if (rootView != null) {
            Bitmap bitmap = Bitmap.createBitmap(rootView.getWidth(), rootView.getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            rootView.draw(canvas);
            saveBitmapToFile(bitmap);
        } else {
            Toast.makeText(getContext(), "Unable to capture screen. View is not ready.", Toast.LENGTH_SHORT).show();
        }
    }


    public void saveBitmapToFile(Bitmap bitmap) {
        String timeStamp = String.valueOf(System.currentTimeMillis());
        File file = new File(getContext().getExternalFilesDir(null), "screenshot_" + timeStamp + ".png");
        try (FileOutputStream fos = new FileOutputStream(file)) {
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
            Toast.makeText(getContext(), "Screenshot saved to: " + file.getAbsolutePath(), Toast.LENGTH_SHORT).show();
        } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(getContext(), "Failed to save screenshot", Toast.LENGTH_SHORT).show();
        }
    }

}
